/* Runtime class information */

#ifndef MC_RT_CLASS_INFO_HPP
#define MC_RT_CLASS_INFO_HPP

#include <cassert>

#include <memchart/class_info.hpp>
#include <memchart/demangle.hpp>
#include <memchart/types.hpp>

namespace memchart
{
	class rt_member_info : public member_info
	{
		public:

			rt_member_info (const string & name, const string & type)
				: member_info(name, type)
			{ }

			virtual ~rt_member_info ()
			{ }

			virtual string read (const void *p) const = 0;
			virtual uintptr_t read_pointer (const void *p) const = 0;
			virtual void write (void *p, const string & val) const = 0;

			string read (uintptr_t obj) const
			{
				return read(reinterpret_cast<void *>(obj));
			}

			uintptr_t read_pointer (uintptr_t obj) const
			{
				return read_pointer(reinterpret_cast<void *>(obj));
			}

			void write (uintptr_t obj, const string & val) const
			{
				write(reinterpret_cast<void *>(obj), val);
			}
	};

	typedef vector<const rt_member_info *> rt_member_vector;

	class rt_class_info : public class_info
	{
		public:

			rt_class_info (const string & name, const rt_member_vector & arr)
				: class_info(demangle(name)),
				arr(arr)
			{
				for (rt_member_vector::const_iterator it = arr.begin();
					it != arr.end(); ++it)
				{
					if (!(*it)->is_pointer())
						np_count++;
				}
			}

			size_t count () const
			{
				return arr.size();
			}

			size_t non_pointer_count () const
			{
				return np_count;
			}

			const rt_member_info & operator [] (size_t i) const
			{
				assert(i < arr.size());

				return *arr[i];
			}

		private:

			const rt_member_vector & arr;
			size_t np_count;
	};
}

#endif /* MC_RT_CLASS_INFO */
